package config

import (
	"api/public/global"
	"context"
	"fmt"
	"gitee.com/dreamwood/ez"
	"go.mongodb.org/mongo-driver/event"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"strings"
	"time"
)

type MongoDbConfig struct {
	User     string   `yaml:"user"`
	Pass     string   `yaml:"pass"`
	Hosts    []string `yaml:"hosts"`
	Auth     string   `yaml:"auth"`
	Db       string   `yaml:"db"`
	LogOn    bool     `yaml:"log-on"`
	LogTo    string   `yaml:"log-to"`
	FilePath string   `yaml:"file"`
	PoolSize uint64   `yaml:"pool-size"`
}

var mdb *mongo.Database

//func init() {
//	initMongoDb()
//}

func InitMongoDb() {

	ez.Debug("MONGODB 开始初始化")
	conf := new(MongoDbConfig)
	ez.CreateConfigFromYml("./app.yaml", "mongodb", &conf)

	uri := fmt.Sprintf(
		"mongodb://%s:%s@%s/%s?authSource=%s&",
		conf.User, conf.Pass,
		strings.Join(conf.Hosts, ","),
		conf.Db, conf.Auth)
	//事件监听输出日志

	ezLogger := ez.CreateLogger()
	switch conf.LogTo {
	case "Nsq":
		ezLogger.NsqPubAddr = GetCore().NsqPubAddr
		ezLogger.InitMqLogger()
		ezLogger.UseMqLogger()
	case "Console":
		ezLogger.InitConsoleLogger()
		ezLogger.UseConsoleLogger()
	case "File":
		ezLogger.FilePath = conf.FilePath
		ezLogger.InitFileLogger()
		ezLogger.UseFileLogger()
	default:
		ezLogger.UseNoLogger()
	}
	m := new(event.CommandMonitor)
	m.Succeeded = func(ctx context.Context, succeededEvent *event.CommandSucceededEvent) {
		if conf.LogOn {
			//调用成功的日志
			timeCost := float64(succeededEvent.DurationNanos) / 1000000
			ezLogger.Printf(fmt.Sprintf("%fms:%s", timeCost, succeededEvent.CommandName))
		}
	}
	m.Started = func(ctx context.Context, startedEvent *event.CommandStartedEvent) {
		if conf.LogOn {
			ezLogger.Printf(startedEvent.Command.String())
		}
	}
	m.Failed = func(ctx context.Context, failEvent *event.CommandFailedEvent) {
		ezLogger.Printf(failEvent.Failure)
	}

	client, err := mongo.NewClient(
		options.Client().ApplyURI(uri).SetMaxPoolSize(conf.PoolSize).SetMonitor(m))
	if err != nil {
		ez.PrintError(err)
	}
	err = client.Connect(context.Background())
	if err != nil {
		ez.PrintError(err)
	}
	ctxTimeout, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	err = client.Ping(ctxTimeout, nil)
	if err != nil {
		ez.PrintError(err)
	}
	mdb = client.Database(conf.Db)
	global.MGO = client.Database(conf.Db)
	ez.Debug("MONGODB 初始化完成")
}

func GetMdb() *mongo.Database {
	if mdb == nil {
		InitMongoDb()
	}
	return mdb
}
